import Vue from 'vue';
import Vuex, {ActionContext, Module} from 'vuex';
import Ajax from '@/lib/ajax';
import Util from '@/lib/util';
import Config from '@/lib/config';
import {appRouters,  otherRouters, flowInstanceRouters,flowSchemeRouters,formSchemeRouters} from '@/router/router';

Vue.use(Vuex);

interface AppState {
    cachePage: any[];
    isFullScreen: boolean;
    openedSubmenuArr: any[];
    menuTheme: string;
    mainTheme: string;
    pageOpenedList: any[];
    currentPageName: string;
    currentPath: any[];
    menuList: any[];
    routers: any[];
    tagsList: any[];
    dontCache: any[];
    currentUser: any;
    loginAttempts: any[];
    userAvatar: string;
}

class AppModule implements Module<AppState, any> {
    namespaced = true;
    state = {
        cachePage: [],
        isFullScreen: false,
        openedSubmenuArr: [],
        menuTheme: 'dark',
        mainTheme: '',
        pageOpenedList: [
            {
                meta: {
                    title: '主页',
                },
                path: '',
                name: 'home',
            },
        ],
        currentPageName: '',
        currentPath: [
            {
                meta: {
                    title: '主页',
                },
                path: '',
                name: 'home',
            },
        ],
        menuList: [],
        routers: [
            flowInstanceRouters,
            flowSchemeRouters,
            formSchemeRouters,
            otherRouters,
            ...appRouters,
        ],
        tagsList: [
            ...otherRouters.children,...flowInstanceRouters.children,...flowSchemeRouters.children,...formSchemeRouters.children,
        ],
        dontCache: [],
        currentUser: {},
        loginAttempts: [],
        userAvatar: '',
    };
    getters = {};
    mutations = {
        logout(state: AppState) {
            localStorage.clear();
            sessionStorage.clear();
        },
        setTagsList(state: AppState, list: any[]) {
            state.tagsList.push(...list);
        },
        updateMenuList(state: AppState) {
            let menuList: Router[] = [];
            appRouters.forEach((item, index) => {
                if (item.permission !== undefined) {
                    let hasPermissionMenuArr: Router[] = [];
                    hasPermissionMenuArr = item.children.filter((child) => {
                        if (child.permission !== undefined) {
                            if (Util.abp.auth.hasPermission(child.permission)) {
                                return child;
                            }
                        } else {
                            return child;
                        }
                    });
                    if (hasPermissionMenuArr.length > 0) {
                        item.children = hasPermissionMenuArr;
                        menuList.push(item);
                    }
                } else {
                    if (item.children.length === 1) {
                        menuList.push(item);
                    } else {
                        let length = menuList.push(item);
                        let childrenArr = item.children.filter((child) => {
                            return child;
                        });
                        let handledItem = JSON.parse(JSON.stringify(menuList[length - 1]));
                        handledItem.children = childrenArr;
                        menuList.splice(length - 1, 1, handledItem);
                    }
                }
            });
            state.menuList = menuList;
        },
        changeMenuTheme(state: AppState, theme: string) {
            state.menuTheme = theme;
        },
        changeMainTheme(state: AppState, mainTheme: string) {
            state.mainTheme = mainTheme;
        },
        addOpenSubmenu(state: AppState, name: any) {

            let hasThisName = false;
            let isEmpty = false;
            if (name.length === 0) {
                isEmpty = true;
            }
            if (state.openedSubmenuArr.indexOf(name) > -1) {
                hasThisName = true;
            }
            if (!hasThisName && !isEmpty) {
                state.openedSubmenuArr.push(name);
            }
        },
        closePage(state: AppState, name: any) {
            state.cachePage.forEach((item, index) => {
                if (item === name) {
                    state.cachePage.splice(index, 1);
                }
            });
        },
        initCachePage(state: AppState) {
            if (localStorage.cachePage) {
                state.cachePage = JSON.parse(localStorage.cachePage);
            }
        },
        removeTag(state: AppState, name: string) {
            state.pageOpenedList.map((item, index) => {
                if (item.name === name) {
                    state.pageOpenedList.splice(index, 1);
                }
            });
        },
        pageOpenedList(state: AppState, get: any) {
            let openedPage = state.pageOpenedList[get.index];
            if (get.arg) {
                openedPage.arg = get.arg;
            }
            if (get.query) {
                openedPage.query = get.query;
            }
            state.pageOpenedList.splice(get.index, 1, openedPage);
            localStorage.pageOpenedList = JSON.stringify(state.pageOpenedList);
        },
        clearAllTags(state: AppState) {
            state.pageOpenedList.splice(1);
            state.cachePage.length = 0;
            localStorage.pageOpenedList = JSON.stringify(state.pageOpenedList);
        },
        clearOtherTags(state: AppState, vm: Vue) {
            let currentName = vm.$route.name;
            let currentIndex = 0;
            state.pageOpenedList.forEach((item, index) => {
                if (item.name === currentName) {
                    currentIndex = index;
                }
            });
            if (currentIndex === 0) {
                state.pageOpenedList.splice(1);
            } else {
                state.pageOpenedList.splice(currentIndex + 1);
                state.pageOpenedList.splice(1, currentIndex - 1);
            }
            state.cachePage = state.cachePage.filter(item => {
                return item === currentName;
            });
            localStorage.pageOpenedList = JSON.stringify(state.pageOpenedList);
        },
        setOpenedList(state: AppState) {
            state.pageOpenedList = localStorage.pageOpenedList ? JSON.parse(localStorage.pageOpenedList) : [otherRouters.children[0]];
        },
        setCurrentPath(state: AppState, pathArr: any[]) {
            state.currentPath = pathArr;
        },
        setCurrentPageName(state: AppState, name: string) {
            state.currentPageName = name;
        },
        clearOpenedSubmenu(state: AppState) {
            state.openedSubmenuArr.length = 0;
        },
        increaseTag(state: AppState, tagObj: any) {
            if (!Util.oneOf(tagObj.name, state.dontCache)) {
                state.cachePage.push(tagObj.name);
                localStorage.cachePage = JSON.stringify(state.cachePage);
            }
            state.pageOpenedList.push(tagObj);
        },
    };
    actions = {
        async authenticate(context: ActionContext<AppState, any>, payload: any) {
            const response = await Ajax.post('/api/TokenAuth/Authenticate', payload.data);
            const tokenExpireDate = payload.data.rememberClient ? (new Date(new Date().getTime() + 1000 * response.data.result.expireInSeconds)) : undefined;
            Util.abp.auth.setToken(response.data.result.accessToken, tokenExpireDate);
            Util.abp.utils.setCookieValue(Config.authorization.encryptedAuthTokenName, response.data.result.encryptedAccessToken, tokenExpireDate, Util.abp.appPath);
        },
        async changePassword(context: ActionContext<AppState, any>, payload: any) {
            await Ajax.post('/api/services/app/Profile/ChangePassword', payload.data);
        },
        async getCurrentUserProfileForEdit(context: ActionContext<AppState, any>, payload: any) {
            const response = await Ajax.get('/api/services/app/Profile/GetCurrentUserProfileForEdit');
            context.state.currentUser = response.data.result;
        },
        async updateCurrentUserProfile(context: ActionContext<AppState, any>, payload: any) {
            await Ajax.put('/api/services/app/Profile/UpdateCurrentUserProfile', payload.data);
        },
        async getRecentUserLoginAttempts(context: ActionContext<AppState, any>, payload: any) {
            const response = await Ajax.get('/api/services/app/UserLogin/GetRecentUserLoginAttempts');
            context.state.loginAttempts = response.data.result.items;
        },
        async updateProfilePicture(context: ActionContext<AppState, any>, payload: any) {
            await Ajax.put('/api/services/app/Profile/UpdateProfilePicture', payload.data);
        },
        async getProfilePicture(context: ActionContext<AppState, any>, payload: any) {
            const response = await Ajax.get('/api/services/app/Profile/GetProfilePicture');
            context.state.userAvatar = response.data.result.profilePicture;
        },
    };
}

const appModule = new AppModule();
export default appModule;
